package tech.cyhk.cloud.demo.order.controller;

import com.alibaba.cloud.nacos.discovery.NacosDiscoveryClient;
import com.alibaba.csp.sentinel.annotation.SentinelResource;
import com.alibaba.csp.sentinel.slots.block.BlockException;
import jakarta.annotation.Resource;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.cloud.client.loadbalancer.LoadBalancerClient;
import org.springframework.cloud.context.config.annotation.RefreshScope;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.client.RestTemplate;
import tech.cyhk.cloud.demo.order.api.ProductFeignClient;
import tech.cyhk.cloud.demo.order.properties.OrderProperties;

/**
 * @author swd
 * @date 2025/1/20
 */
@Slf4j
@RestController
@RequestMapping("/order/hello")
@RequiredArgsConstructor
@RefreshScope
public class OrderHelloController {
    private final RestTemplate restTemplate;
    private final ProductFeignClient productFeignClient;
    private final OrderProperties orderProperties;
    @Resource
    private LoadBalancerClient loadBalancerClient;

//    @Value("${order.hello}")
//    private String helloWord;
//
//    @Value(("${order2.timeout}"))
//    private String timeout;
    @Resource
    private NacosDiscoveryClient nacosDiscoveryClient;

    @GetMapping("config")
    public String config() {
        return "order.timeout=" + orderProperties.getTimeout() + ",order.autoConfirm=" + orderProperties.getAutoConfirm()
                + ",order.databaseName=" + orderProperties.getDatabaseName();
    }


    @GetMapping
    public String hello() {
        String hello = null;

        // nacosDiscoveryClient + 手动负载均衡 + restTemplate(没有@LoadBalanced)
//        List<ServiceInstance> instances = nacosDiscoveryClient.getInstances("service-product");
//        ServiceInstance serviceInstance = instances.get(0);
//        hello = restTemplate.getForObject("http://" + serviceInstance.getHost() + ":" + serviceInstance.getPort() + "/product/hello", String.class);

        //restTemplate + 自动负载均衡(@LoadBalanced)
//        hello = restTemplate.getForObject("http://service-product/product/hello", String.class);

        //使用feign
        hello = productFeignClient.hello();

        log.info("from product: {}", hello);
        return "hello, order; feign execute result:" + hello;
    }

    //======== 测试 热点数据 ========================

    @GetMapping("/hotData")
    @SentinelResource(value = "hotData"
//            , blockHandler = "hotDataBlockHandler"
            , fallback = "hotDataFallback"
    )
    public String hotData(@RequestParam Long id, @RequestParam String name) {
        return "hotData:" + id + ":" + name;
    }

    public String hotDataBlockHandler(Long id, String name, BlockException e) {
        return "hotData blockHandler:" + id + ":" + name + e.getClass();
    }

    /**
     * 热点数据-fallback
     * {@link com.alibaba.csp.sentinel.annotation.aspectj.AbstractSentinelAspectSupport#resolveFallbackInternal} 解析时先用原方法参数查找，未找到再加Throwable
     */
    public String hotDataFallback(Long id, String name, Throwable e) {
        return "hotData fallback:" + id + ":" + name + e.getClass();
    }


    //======== 测试 流控-关联模式 ============

    @GetMapping("writeDB")
    public String writeDB() {
        log.info("writeDB");
        return "writeDB success..";
    }

    @GetMapping("readDB")
    public String readDB() {
        log.info("readDB");
        return "readDB success..";
    }
}
